package ExecuteEngine;

import java.util.List;

import RecordManagement.*;
import SystemManagement.*;
import parse.*;

public class ExecuteEngine {
	public Operation PQplan;
	public SM_Manager sm;
	
	public ExecuteEngine(SM_Manager s){
		this.sm = s;
	}
	
	public Operation PQPlan(LQPlan plan){
		this.PQplan = LogToPhy(plan.GetRoot());
		return PQplan;
	}
	
	public Operation LogToPhy(Algebra plan){
		if(plan instanceof AlgebraTable)
			return new TableScan(((AlgebraTable)plan).tableName, sm);
		else
		if(plan instanceof Index_sigma)
			return new Index_select(((Index_sigma)plan).con, ((Index_sigma)plan).tableName, sm);
		else
		if(plan instanceof Descartes){
			Operation Op1 = LogToPhy(((Descartes)plan).GetA1()),
			          Op2 = LogToPhy(((Descartes)plan).GetA2());
			
			return new CrossProduct(Op1, Op2);
		}
		else
		if(plan instanceof Pi){
			if(((Pi)plan).newname != null)
				return new Project(((Pi)plan).attr_list, LogToPhy(((Pi)plan).son), ((Pi)plan).newname);
			else
				return new Project(((Pi)plan).attr_list, LogToPhy(((Pi)plan).son));
		}
		else
		if(plan instanceof Sigma){
			List<Boolean_term> term = ((Sigma)plan).conditions.condition;
			
			for(int i=0; i<term.size(); i++){
				for(int j=0; j<term.get(i).term.size(); j++){
					Boolean_factor factor = term.get(i).term.get(j);
					if(factor.all != null)
						factor.subquery = LogToPhy(factor.all.CrtAgbPlan(sm).GetRoot());
					else
					if(factor.any != null)
						factor.subquery = LogToPhy(factor.any.CrtAgbPlan(sm).GetRoot());
					else
					if(factor.in != null)
						factor.subquery = LogToPhy(factor.in.CrtAgbPlan(sm).GetRoot());
				}
			}
			
			return new Select(((Sigma)plan).conditions, LogToPhy(((Sigma)plan).son));
		}
		else
		if(plan instanceof NatrualJoin){
			return new Select(((NatrualJoin)plan).tb_list, LogToPhy(((NatrualJoin)plan).son), sm);
		}
		else
		if(plan instanceof Order){
			return new Sort(((Order)plan).order, LogToPhy(((Order)plan).son));
		}
		else
		if(plan instanceof Delete_LQplan){
			return new Delete_operation(LogToPhy(((Delete_LQplan)plan).son), sm);
		}
		if(plan instanceof Update_LQplan){
			return new Update_operation(((Update_LQplan)plan).valuelist, LogToPhy(((Update_LQplan)plan).son), sm);
		}
		
		return null;
	}
}
